#include "playerpage.h"
#include "ui_playerpage.h"
#include <QMouseEvent>
#include "login.h"
#include "toast.h"
#include <QShortcut>
#include "toast.h"
PlayerPage::PlayerPage(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::PlayerPage)
{
    ui->setupUi(this);

    volume = new Volume(this);
    playSpeed = new PlaySpeed(this);// 实例化倍数播放窗⼝对象

    setWindowFlag(Qt::FramelessWindowHint);// 去除边框栏
    setAttribute(Qt::WA_ShowModal, true);// 使窗口变成模态窗口

    mpvPlayer = new MpvPlayer(ui->screen);

    initBarrageArea();
    buildBullectScreenData();
    // 显示弹幕
    showBullectScreen();

    connect(ui->minBtn, &QPushButton::clicked, this, &QWidget::showMinimized);
    connect(ui->quitBtn, &QPushButton::clicked, this, &QWidget::close);
    connect(ui->volumeBtn, &QPushButton::clicked, this, &PlayerPage::onVolumeBtnClicked);
    // 绑定倍数播放按钮信号槽
    connect(ui->speedBtn, &QPushButton::clicked, this, &PlayerPage::onSpeedBtnClicked);
    connect(ui->likeImageBtn, &QPushButton::clicked, this, &PlayerPage::onLikeImageBtnClcked);

    connect(ui->playBtn, &QPushButton::clicked, this, &PlayerPage::onPlayBtnClicked);

    connect(playSpeed, &PlaySpeed::setPlaySpeed, this, &PlayerPage::onPlaySpeedChanged);
    connect(volume, &Volume::setVolume, this, &PlayerPage::setVolume);
    connect(ui->videoSlider, &PlaySlider::setPlayProgress, this, &PlayerPage::onSetPlayProgress);
    connect(mpvPlayer, &MpvPlayer::playPositionChanged, this, &PlayerPage::onPlayPosiionChanged);

    connect(ui->bulletScreenBtn, &QPushButton::clicked, this, &PlayerPage::onBullectScreenBtnClicked);
    connect(ui->bulletScreenText, &BarrageEdit::sendBulletScreen, this, &PlayerPage::onSendBulletScreenBtnClicked);

    // 播放按钮绑定空格快捷键
    QShortcut* shortCut = new QShortcut(ui->playBtn);
    QKeySequence keySequence(" ");
    shortCut->setKey(keySequence);
    connect(shortCut, &QShortcut::activated, this, [=](){
        ui->playBtn->animateClick();
    });
}

PlayerPage::~PlayerPage()
{
    delete ui;
    delete mpvPlayer;
}

void PlayerPage::mousePressEvent(QMouseEvent *event)
{
    // 先要获取鼠标按下时相对于窗口的位置, 检查窗口是否在窗口的head内部
    QPoint point = event->position().toPoint();
    if(ui->playHead->geometry().contains(point))
    {
        if(event->button() == Qt::LeftButton)
        {
            // 计算鼠标按下之后的全局坐标和窗口左上角的相对偏移
            // 整个移动过程中，该偏移不能发生改变
            dragPos = event->globalPosition().toPoint() - geometry().topLeft();
            return;
        }
    }
    QWidget::mousePressEvent(event);
}

void PlayerPage::mouseMoveEvent(QMouseEvent *event)
{
    QPoint point = event->position().toPoint();
    if(ui->playHead->geometry().contains(point))
    {
        if(event->buttons() == Qt::LeftButton)
        {
            move(event->globalPosition().toPoint() - dragPos);

            // 移动弹幕窗口到播放窗口的head下方
            QPoint point = geometry().topLeft();
            point.setY(point.ry() + ui->playHead->height());
            barrageArea->move(point);
        }
    }
    QWidget::mousePressEvent(event);
}

void PlayerPage::startPlaying(const QString &videoPath)
{
    // 先保存视频路径, 后序重新播放时需要用到该路径
    this->videoPath = videoPath;

    mpvPlayer->startPlay(videoPath);

    // 视频加载成功之后会立马播放，初始时先将其设置为暂停状态
    mpvPlayer->pause();
}

void PlayerPage::moveWindows(const QPoint& point)
{
    // QPoint(this->width() - volume->width()-13: 13是⾳量调节窗⼝右边界和PlayerPage的右边界的距离
    // 533是⾳量调节窗⼝距离PlayerPage上边界的距离
    // newPoint最终为⾳量调节窗⼝在PlayerPage中的位置转化的全局坐标
    QPoint newPoint = point + QPoint(this->width() - volume->width() - 13, 533);
    volume->move(newPoint);

    // 倍数播放窗口位置调整
    newPoint = point + QPoint(this->width() - playSpeed->width() - 72, 563);
    playSpeed->move(newPoint);
}

QString PlayerPage::secondToTime(int64_t seconds)
{
    QString time;
    // 小时：存在时显示
    if(seconds / 60 / 60)
    {
        time += QString::asprintf("%02lld", seconds / 60/ 60);
    }

    // 拼接时分秒
    time += QString::asprintf("%02lld:%02lld", seconds/60, seconds%60);
    return time;
}

void PlayerPage::initBarrageArea()
{
    // 创建弹幕显示区域对话框，该对话框没有边框，背景透明
    barrageArea = new QDialog(this);
    barrageArea->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
    barrageArea->setAttribute(Qt::WA_TranslucentBackground);
    barrageArea->setMinimumSize(this->width(), 38*3);

    // 垂直布局器，添加到对话框
    QVBoxLayout* layout = new QVBoxLayout(barrageArea);
    barrageArea->setLayout(layout);

    // 在弹幕区域添加用来显示三行弹幕的控件
    top = new QFrame(this);
    top->setFixedSize(this->width(), 38);

    middle = new QFrame(this);
    middle->setFixedSize(this->width(), 38);

    bottom= new QFrame(this);
    bottom->setFixedSize(this->width(), 38);

    layout->addWidget(top);
    layout->addWidget(middle);
    layout->addWidget(bottom);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);

    // 移动弹幕窗⼝到播放窗⼝的head底下
    QPoint point = mapToGlobal(QPoint(0, 0));
    point.setY(point.y() + ui->playHead->height());
    barrageArea->move(point);
    barrageArea->show();
}

void PlayerPage::buildBullectScreenData()
{
    QList<BullectScreenInfo> bullectScreenList;

    for(int i = 1; i <= 3; ++i)
    {
        BullectScreenInfo bsItem("100001", i, "我是弹幕" + QString::number(i));
        bullectScreenList.append(bsItem);
        bullectScreens.insert(bsItem.playTime, bullectScreenList);
        bullectScreenList.clear();
    }

    // 构造相同时间点下的多条弹幕
    for(int i = 0; i < 4; i++)
    {
        BullectScreenInfo bsItem("100014", 5, "我是弹幕" + QString::number(i));
        bullectScreenList.append(bsItem);
    }
    bullectScreens.insert(bullectScreenList[0].playTime, bullectScreenList);
}

void PlayerPage::showBullectScreen()
{
    // 如果打开关闭时，弹幕不需要添加到界面中
    if(!isStartBs)
    {
        return;
    }

    // 1. 获取当前playTime点的所有弹幕
    QList<BullectScreenInfo> bullectScreenList = bullectScreens.value(playTime);
    int xTop, xMiddle, xBottom;
    xTop = xMiddle = xBottom = top->width();
    BullectScreenItem* bsItem = nullptr;
    // 2. 将弹幕显示出来
    for(int i = 0; i < bullectScreenList.size(); i++)
    {
        BullectScreenInfo& bsInfo = bullectScreenList[i];
        if(i % 3 == 0)
        {
            bsItem = new BullectScreenItem(top);
            bsItem->setBullectScreenText(bsInfo.text);

            int duration = 10000 * xTop / (double)(top->width() + 30*18);
            bsItem->setBullectScreenAnimation(xTop, duration);
            xTop += bsItem->width() + 4 *18;
        }
        else if(i % 3 == 1)
        {
            bsItem = new BullectScreenItem(middle);
            bsItem->setBullectScreenText(bsInfo.text);
            // 给弹幕设置动画属性w
            int duration = 10000 * xMiddle / (double)(middle->width() + 30*18);
            bsItem->setBullectScreenAnimation(xMiddle, duration);
            xMiddle += bsItem->width() + 4 *18;
        }
        else
        {
            bsItem = new BullectScreenItem(bottom);
            bsItem->setBullectScreenText(bsInfo.text);

            int duration = 10000 * xBottom / (double)(bottom->width() + 30*18);
            bsItem->setBullectScreenAnimation(xBottom + 2 * 18, duration);
            xBottom += bsItem->width() + 4 *18;
        }
        bsItem->startAnimation();
    }
}

void PlayerPage::onVolumeBtnClicked()
{
    // QPoint(0, 0)为PlayerPage窗⼝的左上⻆
    // mapToGlobal(QPoint(0, 0))将PlayerPage窗⼝左上⻆转换为全局坐标
    moveWindows(mapToGlobal(QPoint(0, 0))); // 新增调⽤
    volume->show();
}

// 新增
void PlayerPage::onSpeedBtnClicked()
{
    moveWindows(mapToGlobal(QPoint(0, 0)));
    // 弹出倍速窗⼝
    playSpeed->show();
}

void PlayerPage::onLikeImageBtnClcked()
{
    Login* login = new Login();
    Toast::showMessage("先登录, 登录完成之后才能点赞", login);
}

void PlayerPage::onPlayBtnClicked()
{
    isPlay = !isPlay;
    if(isPlay)
    {
        ui->playBtn->setStyleSheet("border-image : url(:/images/PlayPage/bofang.png)");
        mpvPlayer->play();
    }
    else
    {
        ui->playBtn->setStyleSheet("border-image : url(:/images/PlayPage/zanting.png)");
        mpvPlayer->pause();
    }
    if(playTime == 10 && isPlay)
    {
        startPlaying(videoPath);
    }
}

void PlayerPage::onPlaySpeedChanged(double speed)
{
    mpvPlayer->setPlaySpeed(speed);
}

void PlayerPage::setVolume(int volume)
{
    mpvPlayer->setVolume(volume);
}

void PlayerPage::onPlayPosiionChanged(int64_t playTime)
{
    this->playTime = playTime;
    int64_t videoTotalTime = 10;
    QString curPlayTime = secondToTime(playTime);
    QString totalTime = secondToTime(videoTotalTime);
    ui->videoDuration->setText(curPlayTime + "/" + totalTime);

    ui->videoSlider->setPlayStep((double)playTime / videoTotalTime);
    // 当视频播放完整之后
    if(10 == playTime)
    {
        isPlay = false;
        ui->playBtn->setStyleSheet("border-image : url(:/images/PlayPage/zanting.png)");
    }

    // 更新弹幕数据
    showBullectScreen();
}

void PlayerPage::onSetPlayProgress(double playRatio)
{
    playTime = playRatio * 10;
    mpvPlayer->setCurrentPlayPosition(playTime);
}

void PlayerPage::onBullectScreenBtnClicked()
{
    isStartBs = !isStartBs;
    if(isStartBs)
    {
        // 弹幕开
        ui->bulletScreenBtn->setStyleSheet("border-image : url(:/images/PlayPage/danmu.png)");
        barrageArea->show();
    }
    else
    {
        // 弹幕关
        ui->bulletScreenBtn->setStyleSheet("border-image : url(:/images/PlayPage/danmuguan.png)");
        barrageArea->hide();
    }
}

void PlayerPage::onSendBulletScreenBtnClicked(const QString& text)
{
    // 如果弹幕窗口关闭，则不能发送弹幕
    if(!isStartBs)
    {
        Toast::showMessage("请打开弹幕开关");
        return;
    }
    BullectScreenItem* bsItem = new BullectScreenItem(top);
    bsItem->setBullectScreenText(text);
    QPixmap pixmap(":/images/homePage/touxiang.png");
    bsItem->setBullectScreenIcon(pixmap);
    int64_t duration = 10000 * top->width() / (double)(top->width() + 30 * 18);
    bsItem->setBullectScreenAnimation(top->width(), duration);
    bsItem->startAnimation();
}




